<script setup lang="ts">
import { computed, reactive, watch } from 'vue';
import { addCollectionRule, updateCollectionRule } from '@/service/api';
import { formRules, getConfirmText, getTitle } from '@/utils/form';

defineOptions({
  name: 'RuleOperateDrawer'
});

interface Props {
  operateType: AntDesign.TableOperateType;
  rowData?: Api.Dataplatform.CollectionRuleDetail | null;
}

const props = defineProps<Props>();

interface Emits {
  (e: 'submitted'): void;
}

const emit = defineEmits<Emits>();

const visible = defineModel<boolean>('visible', {
  default: false
});

const title = computed(() => getTitle(props.operateType));
const confirmText = computed(() => getConfirmText(props.operateType));

const model: Api.Dataplatform.CollectionRuleEdit = reactive(createDefaultModel());

function createDefaultModel(): Api.Dataplatform.CollectionRuleEdit {
  return {
    id: null,
    ruleName: '',
    ruleCode: '',
    fileType: 'CSV',
    sourceType: 'LOCAL',
    sourceConfig: '{}',
    scheduleType: 'MANUAL',
    scheduleConfig: '',
    targetDatabase: '',
    targetTable: '',
    loadStrategy: 'APPEND',
    status: 'DISABLED',
    mappingRuleId: null,
    remark: ''
  };
}

// 生成规则编码的函数
function generateRuleCode(ruleName: string): string {
  if (!ruleName) return '';
  
  // 移除特殊字符，只保留字母、数字和中文
  const cleanName = ruleName.replace(/[^\w\u4e00-\u9fa5]/g, '');
  
  // 转换为拼音首字母或保留英文字母
  const pinyin = cleanName.replace(/[\u4e00-\u9fa5]/g, (char) => {
    // 这里可以集成拼音库，暂时用简单的映射
    return char.charCodeAt(0).toString(36).toUpperCase();
  });
  
  // 生成时间戳后缀
  const timestamp = Date.now().toString().slice(-6);
  
  // 组合规则编码：前缀 + 时间戳
  return `RULE_${pinyin.toUpperCase()}_${timestamp}`;
}

// 监听规则名称变化，自动生成规则编码
watch(
  () => model.ruleName,
  (newRuleName) => {
    // 只在新增模式下且规则编码为空时自动生成
    if (props.operateType === 'add' && newRuleName && !model.ruleCode) {
      model.ruleCode = generateRuleCode(newRuleName);
    }
  }
);

const rules = {
  ruleName: [{ required: true, message: '请输入规则名称', trigger: ['blur', 'input'] }],
  ruleCode: [{ required: true, message: '请输入规则编码', trigger: ['blur', 'input'] }],
  fileType: [{ required: true, message: '请选择文件类型', trigger: 'change' }],
  sourceType: [{ required: true, message: '请选择来源类型', trigger: 'change' }],
  scheduleType: [{ required: true, message: '请选择调度类型', trigger: 'change' }],
  targetDatabase: [{ required: true, message: '请输入目标数据库', trigger: ['blur', 'input'] }],
  targetTable: [{ required: true, message: '请输入目标表', trigger: ['blur', 'input'] }],
  loadStrategy: [{ required: true, message: '请选择入库策略', trigger: 'change' }]
};

const fileTypeOptions = [
  { label: 'CSV', value: 'CSV' },
  { label: 'Excel(XLS)', value: 'XLS' },
  { label: 'Excel(XLSX)', value: 'XLSX' },
  { label: 'XML', value: 'XML' },
  { label: 'JSON', value: 'JSON' },
  { label: 'SQL脚本', value: 'SQL' }
];

const sourceTypeOptions = [
  { label: '本地文件', value: 'LOCAL' },
  { label: 'FTP', value: 'FTP' },
  { label: 'SFTP', value: 'SFTP' },
  { label: 'HTTP', value: 'HTTP' },
  { label: '对象存储', value: 'OSS' }
];

const scheduleTypeOptions = [
  { label: '实时', value: 'REALTIME' },
  { label: '每小时', value: 'HOURLY' },
  { label: '每天', value: 'DAILY' },
  { label: '每周', value: 'WEEKLY' },
  { label: '每月', value: 'MONTHLY' },
  { label: '手动触发', value: 'MANUAL' }
];

const loadStrategyOptions = [
  { label: '全量覆盖', value: 'OVERWRITE' },
  { label: '增量追加', value: 'APPEND' },
  { label: '按主键更新', value: 'UPSERT' }
];

const sourceConfigModel = reactive({
  path: '',
  pattern: '*',
  host: '',
  port: 21,
  username: '',
  password: '',
  url: '',
  bucketName: '',
  prefix: ''
});

watch(
  () => props.rowData,
  newValue => {
    if (newValue) {
      Object.assign(model, newValue);
      if (newValue.sourceConfig) {
        try {
          const config = JSON.parse(newValue.sourceConfig);
          Object.assign(sourceConfigModel, config);
        } catch (e) {
          console.error('解析来源配置失败', e);
        }
      }
    }
  },
  { immediate: true }
);

watch(
  () => visible.value,
  newValue => {
    if (!newValue) {
      Object.assign(model, createDefaultModel());
      Object.assign(sourceConfigModel, {
        path: '',
        pattern: '*',
        host: '',
        port: 21,
        username: '',
        password: '',
        url: '',
        bucketName: '',
        prefix: ''
      });
    }
  }
);

watch(
  sourceConfigModel,
  () => {
    model.sourceConfig = JSON.stringify(sourceConfigModel);
  },
  { deep: true }
);

async function handleSubmit() {
  const api = props.operateType === 'add' ? addCollectionRule : updateCollectionRule;
  const { error } = await api(model);
  if (!error) {
    window.$message?.success(confirmText.value);
    closeDrawer();
    emit('submitted');
  }
}

function closeDrawer() {
  visible.value = false;
}

// 手动生成规则编码的处理函数
function handleGenerateRuleCode() {
  if (model.ruleName) {
    model.ruleCode = generateRuleCode(model.ruleName);
    window.$message?.success('规则编码已自动生成');
  } else {
    window.$message?.warning('请先输入规则名称');
  }
}
</script>

<template>
  <NDrawer v-model:show="visible" display-directive="show" :width="720">
    <NDrawerContent :title="title" :native-scrollbar="false" closable>
      <NForm :model="model" :rules="rules" label-placement="left" :label-width="120">
        <NGrid :cols="24" :x-gap="18">
          <NFormItemGridItem :span="24" label="规则名称" path="ruleName">
            <NInput v-model:value="model.ruleName" placeholder="请输入规则名称" />
          </NFormItemGridItem>
          <NFormItemGridItem :span="24" label="规则编码" path="ruleCode">
            <NInputGroup>
              <NInput v-model:value="model.ruleCode" placeholder="请输入规则编码或点击自动生成" />
              <NButton 
                type="primary" 
                ghost 
                @click="handleGenerateRuleCode"
                :disabled="!model.ruleName"
              >
                自动生成
              </NButton>
            </NInputGroup>
          </NFormItemGridItem>
          <NFormItemGridItem :span="12" label="文件类型" path="fileType">
            <NSelect v-model:value="model.fileType" :options="fileTypeOptions" placeholder="请选择文件类型" />
          </NFormItemGridItem>
          <NFormItemGridItem :span="12" label="来源类型" path="sourceType">
            <NSelect v-model:value="model.sourceType" :options="sourceTypeOptions" placeholder="请选择来源类型" />
          </NFormItemGridItem>

          <!-- 本地文件配置 -->
          <template v-if="model.sourceType === 'LOCAL'">
            <NFormItemGridItem :span="24" label="文件路径">
              <NInput v-model:value="sourceConfigModel.path" placeholder="请输入文件路径" />
            </NFormItemGridItem>
            <NFormItemGridItem :span="24" label="文件名模式">
              <NInput v-model:value="sourceConfigModel.pattern" placeholder="文件名模式，如 *.csv" />
            </NFormItemGridItem>
          </template>

          <!-- FTP/SFTP配置 -->
          <template v-if="model.sourceType === 'FTP' || model.sourceType === 'SFTP'">
            <NFormItemGridItem :span="12" label="主机地址">
              <NInput v-model:value="sourceConfigModel.host" placeholder="请输入主机地址" />
            </NFormItemGridItem>
            <NFormItemGridItem :span="12" label="端口">
              <NInputNumber v-model:value="sourceConfigModel.port" placeholder="端口" class="w-full" />
            </NFormItemGridItem>
            <NFormItemGridItem :span="12" label="用户名">
              <NInput v-model:value="sourceConfigModel.username" placeholder="请输入用户名" />
            </NFormItemGridItem>
            <NFormItemGridItem :span="12" label="密码">
              <NInput v-model:value="sourceConfigModel.password" type="password" placeholder="请输入密码" />
            </NFormItemGridItem>
            <NFormItemGridItem :span="24" label="文件路径">
              <NInput v-model:value="sourceConfigModel.path" placeholder="请输入文件路径" />
            </NFormItemGridItem>
            <NFormItemGridItem :span="24" label="文件名模式">
              <NInput v-model:value="sourceConfigModel.pattern" placeholder="文件名模式，如 *.csv" />
            </NFormItemGridItem>
          </template>

          <!-- HTTP配置 -->
          <template v-if="model.sourceType === 'HTTP'">
            <NFormItemGridItem :span="24" label="文件URL">
              <NInput v-model:value="sourceConfigModel.url" placeholder="请输入文件URL" />
            </NFormItemGridItem>
          </template>

          <!-- OSS配置 -->
          <template v-if="model.sourceType === 'OSS'">
            <NFormItemGridItem :span="12" label="存储桶名称">
              <NInput v-model:value="sourceConfigModel.bucketName" placeholder="请输入存储桶名称" />
            </NFormItemGridItem>
            <NFormItemGridItem :span="12" label="文件前缀">
              <NInput v-model:value="sourceConfigModel.prefix" placeholder="请输入文件前缀" />
            </NFormItemGridItem>
            <NFormItemGridItem :span="24" label="文件名模式">
              <NInput v-model:value="sourceConfigModel.pattern" placeholder="文件名模式，如 *.csv" />
            </NFormItemGridItem>
          </template>

          <NFormItemGridItem :span="12" label="调度类型" path="scheduleType">
            <NSelect v-model:value="model.scheduleType" :options="scheduleTypeOptions" placeholder="请选择调度类型" />
          </NFormItemGridItem>
          <NFormItemGridItem v-if="model.scheduleType !== 'MANUAL'" :span="12" label="Cron表达式">
            <NInput v-model:value="model.scheduleConfig" placeholder="请输入Cron表达式" />
          </NFormItemGridItem>
          <NFormItemGridItem :span="12" label="目标数据库" path="targetDatabase">
            <NInput v-model:value="model.targetDatabase" placeholder="请输入目标数据库" />
          </NFormItemGridItem>
          <NFormItemGridItem :span="12" label="目标表" path="targetTable">
            <NInput v-model:value="model.targetTable" placeholder="请输入目标表" />
          </NFormItemGridItem>
          <NFormItemGridItem :span="12" label="入库策略" path="loadStrategy">
            <NSelect v-model:value="model.loadStrategy" :options="loadStrategyOptions" placeholder="请选择入库策略" />
          </NFormItemGridItem>
          <NFormItemGridItem :span="24" label="备注">
            <NInput v-model:value="model.remark" type="textarea" placeholder="请输入备注" />
          </NFormItemGridItem>
        </NGrid>
      </NForm>
      <template #footer>
        <NSpace justify="end">
          <NButton @click="closeDrawer">取消</NButton>
          <NButton type="primary" @click="handleSubmit">{{ confirmText }}</NButton>
        </NSpace>
      </template>
    </NDrawerContent>
  </NDrawer>
</template>

<style scoped></style>
